using System;
using System.Collections.Generic;

namespace lucere.io
{
	/// <summary>
	/// Abstract base class for output to a file in a Directory.  A random-access
	/// output stream.  Used for all Lucene index output operations.
	///<see>Directory</see>
	///<see>IndexInput</see>
	/// </summary>
	public interface IIndexOutput: IDisposable
	{
		/// <summary>Writes a single byte.
		/// <see>IndexInput ReadByte()</see>
		/// </summary>
		void WriteByte(byte b);

		/// <summary>
		/// Writes an array of bytes.
		/// <param name="b">the bytes to write</param>
		/// <param name="length">length the number of bytes to write</param>
		/// <see>IndexInput readBytes(byte[],int,int)</see>
		/// </summary>
		void WriteBytes(byte[] b, int length);

		///<summary>Writes an array of bytes.
		///</summary>
		/// <param name="b">the bytes to write</param>
		/// <param name="length">length the number of bytes to write</param>
		/// <param name="offset">offset the offset in the byte array</param>
		/// <see cref="IndexInput">ReadBytes(byte[],int,int)</see>
		void WriteBytes(byte[] b, int offset, int length);

		///<summary>Writes an int as four bytes.</summary>
		///<see>IndexInput#readInt()</see>
		void WriteInt(int i);

		///<summary>
		/// Writes an int in a variable-length format.  Writes between one and
		/// five bytes.  Smaller values take fewer bytes.  Negative numbers are not
		/// supported.
		/// </summary>
		/// <see cref="IndexInput#readVInt()"></see>
		void WriteVInt(int i);

		///<summary>Writes a long as eight bytes.</summary>
		/// <see cref="IndexInput#readLong()"></see>
		void WriteLong(long i);
		
		///<summary>
		/// Writes an long in a variable-length format.  Writes between one and five
		/// bytes.  Smaller values take fewer bytes.  Negative numbers are not
		/// supported.
		///</summary>
		/// <see cref="IndexInput#readVLong()"></see>
		void WriteVLong(long i);

		///<summary>
		/// Writes a string.
		///</summary>
		/// <see cref="IndexInput#readString()"></see>
		void WriteString(string s);

		///<summary>Copy numBytes bytes from input to ourself.
		/// </summary>
		void CopyBytes(IIndexInput input, long numBytes);

		///<summary>Forces any buffered output to be written.
		/// </summary>
		void Flush();

		///<summary>
		/// Returns the current position in this file, where the next write will occur.
		/// </summary>
		/// <see cref="seek(long)"></see>
		long GetFilePointer();

		///<summary>
		/// Sets current position in this file, where the next write will occur.
		/// </summary>
		/// <see cref="#getFilePointer()"></see>
		void Seek(long pos);

		///<summary>The number of bytes in the file.
		/// Set the file length. By default, this method does
		/// nothing (it's optional for a Directory to implement
		/// it).  But, certain Directory implementations (for
		/// example @see FSDirectory) can use this to inform the
		/// underlying IO system to pre-allocate the file to the
		/// specified size.  If the length is longer than the
		/// current file length, the bytes added to the file are
		/// undefined.  Otherwise the file is truncated.
		/// @param length file length
		/// </summary>
		long Length { get; set; }

		void WriteStringStringMap(IDictionary<string, string> map);
	}
}